package com.borball.store.comp;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.ListSelectionModel;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import javax.swing.table.TableRowSorter;

import com.borball.store.dao.CompositeDAO;
import com.borball.store.dao.PStoreLogDAO;
import com.borball.store.dao.ProductOutCheckDAO;
import com.borball.store.dao.ProductStoreDAO;
import com.borball.store.domain.Composite;
import com.borball.store.domain.OutCheckStatus;
import com.borball.store.domain.PStoreLog;
import com.borball.store.domain.ProductAmount;
import com.borball.store.domain.ProductOutCheck;
import com.borball.store.domain.ProductStore;
import com.borball.store.domain.User;
import com.borball.store.util.StoreChangeActions;
import com.borball.store.util.UserUtils;

import craky.component.CommonTableModel;
import craky.componentc.JCButton;
import craky.componentc.JCComboBox;
import craky.componentc.JCLabel;
import craky.componentc.JCMessageBox;
import craky.componentc.JCNumberField;
import craky.componentc.JCScrollTable;
import craky.componentc.JCScrollText;
import craky.componentc.JCTable;
import craky.componentc.JCTableHeader;
import craky.keeper.EmptyComponent;
import craky.keeper.KeeperApp;
import craky.keeper.KeeperPane;
import craky.layout.LineLayout;

public class CardAndMaterailCheckPane extends KeeperPane {

	private static final long serialVersionUID = 2583431180094797757L;

	protected JCTable table;
	protected List<ProductOutCheck> data;
	protected CommonTableModel<ProductOutCheck> model;
	private static final String[] COLUMNS_NAME = { "出仓流水", "成品数量", "当前库存", "应还数量", "状态",  "经手人", "最近修改时间"};
	protected JComponent bottom, center;
	private JCButton btnInsert;
	protected JCNumberField cpAmount, cpOutId;
	protected JCScrollText cpMemo;
	protected JCComboBox cpType, cpUser;
	protected JComponent ecOutId, ecAmount, ecType, ecMemo, ecUser;
	protected Action insertAction;
	protected KeeperApp keeper;
	protected User currentUser;

	CompositeDAO compositeDAO = new CompositeDAO();
	ProductOutCheckDAO productOutCheckDAO = new ProductOutCheckDAO();
	ProductStoreDAO productStoreDAO = new ProductStoreDAO();

	public CardAndMaterailCheckPane(KeeperApp keeper) {
		this.keeper = keeper;
		this.currentUser = keeper.getCurrentUser();
		loadData();
		initActions();
		initUI();
		cpOutId.addFocusListener(new FocusListener() {
			
			public void focusLost(FocusEvent e) {
				//reload data
				if("".equals(cpOutId.getText()) || cpOutId.getText() == null){
					
				}
				else {
					data = new ArrayList<ProductOutCheck>();
					
					ProductOutCheck check = productOutCheckDAO.findByPK(cpOutId.getText());
					
					if (check != null) {
						data.clear();
						data.add(check);
						loadDataByOutId(Integer.valueOf(cpOutId.getText()));
						model.delAllRow();
						model.setDataList(data);
						model.getTable().repaint();
						model.refreshRowOnView(0);
						if(check.getStatus().equals(OutCheckStatus.FULL.getMessage())){
							resetTextStatus(false);
						}
					} else {
						
						resetTextStatus(false);
					}

				}
				
			}
			
			public void focusGained(FocusEvent e) {
				resetTextStatus(true);
			}
		});
		
	}
	
	private void loadDataByOutId(int id) {
		data = new ArrayList<ProductOutCheck>();
		data.clear();
		if (productOutCheckDAO.findByPK(id) != null)
			data.add(productOutCheckDAO.findByPK(id));
	}

	private void initActions() {
		insertAction = new AbstractAction("入库") {
			private static final long serialVersionUID = 5056698643009336063L;

			public void actionPerformed(ActionEvent e) {
				insertOrModify(true);
			}
		};

	}

	public void insertOrModify(boolean insert) {
		if(insert){
			if(checkNull()){
				updateStore();
				
				loadData();
				model.delAllRow();
				model.setDataList(data);
				model.getTable().repaint();
				model.refreshRowOnView(0);

				reset();
			}

		}
	}

	private boolean checkNull() {
		if (cpType.getSelectedItem() == null || "".equals(cpAmount.getText()) || cpUser.getSelectedItem() == null
				|| "".equals(cpOutId.getText())) {

			JCMessageBox.createErrorMessageBox(keeper.getMainFrame(), "必填项为空", "请输入所有必填项").open();

			cpOutId.requestFocus();
			return false;
		}

		ProductOutCheck poc = productOutCheckDAO.findByPK(Integer.valueOf(cpOutId.getText()));
		if(poc!=null){
			ProductAmount[] pas = poc.string2ProductAmount(poc.getNeedProducts());
			for (ProductAmount productAmount : pas) {
				if(productAmount.getName().equals(cpType.getSelectedItem().toString().trim())){
					if(productAmount.getAmount() < Integer.valueOf(cpAmount.getText())){
						JCMessageBox.createErrorMessageBox(keeper.getMainFrame(), "入库数量大于应还数量", "入库数量大于应还数量,请核对!").open();
						cpOutId.requestFocus();
						return false;
					}
				}
			}
		}
		
		return true;
	}

	private void updateStore() {
		ProductStore store = productStoreDAO.findByPK(cpType.getSelectedItem());
		int originalStore = 0;
		int currentStore = 0;
		if(store == null){
			store = new ProductStore();
			currentStore = Integer.valueOf(cpAmount.getText());
			store.setName(cpType.getSelectedItem().toString());
			store.setAmount(currentStore);
			store.setUnit(compositeDAO.findByPK(cpType.getSelectedItem().toString()).getUnit());
			
			store.setModified(new Timestamp(System.currentTimeMillis()));
			productStoreDAO.add(store);
		} else {
			originalStore = store.getAmount();
			currentStore = originalStore + Integer.valueOf(cpAmount.getText());
			store.setAmount(currentStore);
			store.setModified(new Timestamp(System.currentTimeMillis()));
			productStoreDAO.updateStore(store);
		}
		addCheckLog(StoreChangeActions.IN, cpType.getSelectedItem().toString(), Integer.valueOf(cpAmount.getText()),
				cpMemo.getEditor().getText(), cpUser.getSelectedItem().toString(), currentUser.getName(), Integer.valueOf(cpOutId.getText()));
		
	}

	private void resetTextStatus(boolean enabled) {
		 cpType.setEnabled(enabled);
		 cpAmount.setEnabled(enabled);
		 cpMemo.setEnabled(enabled);
		 cpUser.setEnabled(enabled);
		 btnInsert.setEnabled(enabled);
	}

	private void reset() {
//		cpOutId.setText(null);
		cpAmount.setText(null);
		cpType.setSelectedIndex(-1);
//		cpUser.setSelectedIndex(-1);
//		cpMemo.getEditor().setText(null);
	}
	
	private void addCheckLog(StoreChangeActions action, String product, Integer amount, String memo, String user, String operator, int outId) {
		PStoreLog log = new PStoreLog();
		log.setAction(action.getMessage());
		log.setAmount(amount);
		log.setUser(user);
		log.setPid(product);
		log.setCreated(new Timestamp(System.currentTimeMillis()));
		log.setMemo(memo);
		log.setOutId(outId);
		log.setOperator(operator);
		PStoreLogDAO dao = new PStoreLogDAO();
		dao.add(log);
		
		ProductOutCheck poc = productOutCheckDAO.findByPK(log.getOutId());
		if(poc!=null){
			poc.setCreated(new Timestamp(System.currentTimeMillis()));
			updateNeedsProducts(poc, product, amount);
			
			poc.setMemo(poc.getMemo() + "|" + memo);
			productOutCheckDAO.update(poc);
		}
	}
	
	private void updateNeedsProducts(ProductOutCheck poc, String product, Integer amount){
		String needs = poc.getNeedProducts();
		String reals = poc.getRealProducts();
		
		ProductAmount[] paNeeds = poc.string2ProductAmount(needs);
		ProductAmount[] paReals = poc.string2ProductAmount(reals);
		
		for (ProductAmount productAmount : paNeeds) {
			if(productAmount.getName().equals(product)){
				productAmount.setAmount(productAmount.getAmount() - amount);
			}
		}
		
		needs = poc.productAmount2String(paNeeds);

		for (ProductAmount productAmount : paReals) {
			if(productAmount.getName().equals(product)){
				productAmount.setAmount(productAmount.getAmount() + amount);
			}
		}
		reals = poc.productAmount2String(paReals);
		
		poc.setRealProducts(reals);
		poc.setNeedProducts(needs);
		
		if(reals.equals(poc.getShouldProducts())){
			poc.setStatus(OutCheckStatus.FULL.getMessage());
		} else {
			poc.setStatus(OutCheckStatus.PART.getMessage());
		}
		
	}
	public void loadData() {
		data = productOutCheckDAO.findAll();
		
		keeper.refreshStatus();
	}

	private void initUI() {
		btnInsert = new JCButton(insertAction);
		btnInsert.setPreferredSize(new Dimension(75, 30));
		EmptyComponent centerParent = new EmptyComponent();
		setLayout(new BorderLayout());
		centerParent.setLayout(new BorderLayout(0, 3));
		createCenter();
//		createTop();
		createBottom();
//		createLeft();
//		createRight();
		this.add(centerParent, BorderLayout.CENTER);

		if (center != null) {
			centerParent.add(center, BorderLayout.CENTER);
		}

		if (bottom != null) {
			centerParent.add(bottom, BorderLayout.NORTH);
		}
		
		loadTypes();
		loadUsers();
//		loadUnits();

	}

	private void loadUsers() {
		List<User> users = UserUtils.getInstance().getAllUsers();
		
		cpUser.removeAllItems();
		for (User user : users) {
			cpUser.addItem(user.getName());
		}
		cpUser.setSelectedItem(keeper.getCurrentUser());
		
	}

	private void loadTypes() {
		List<Composite> composites = compositeDAO.findAll();
		
		cpType.removeAllItems();
		for (Composite c : composites) {
			cpType.addItem(c.getName());
		}
		cpType.setSelectedItem(-1);
	}

	private JComponent createBottom() {
		int leftGap = 0;
		int rightGap = 0;
		bottom = new EmptyComponent();
		bottom.setBorder(new CompoundBorder(new EmptyBorder(0, leftGap, 0, rightGap), new LineBorder(new Color(84, 165,
				213))));
		bottom.setPreferredSize(new Dimension(-1, 77));
		bottom.setLayout(new BorderLayout());
		bottom.add(createDetailComponent(), BorderLayout.CENTER);

		EmptyComponent buttonContainer = new EmptyComponent();
		buttonContainer.setLayout(new LineLayout(3, 0, 5, 0, 3, LineLayout.TRAILING, LineLayout.TRAILING,
				LineLayout.VERTICAL));
		buttonContainer.setPreferredSize(new Dimension(85, -1));

		buttonContainer.add(btnInsert, LineLayout.END_FILL);
		bottom.add(buttonContainer, BorderLayout.EAST);

		return bottom;

	}

	private Component createDetailComponent() {
		EmptyComponent ec = new EmptyComponent();
		EmptyComponent firstRow = new EmptyComponent();
		EmptyComponent secondRow = new EmptyComponent();
		JCLabel lbOutId = new JCLabel("元件出仓流水");
		JCLabel lbAmount = new JCLabel("数量");
//		JCLabel lbUnit = new JCLabel("单位");
		JCLabel lbType = new JCLabel("类型");
		JCLabel lbUser = new JCLabel("入库人员");
		JCLabel lbMemo = new JCLabel("备注");
		Border border = new EmptyBorder(0, 0, 0, 5);
		cpOutId = new JCNumberField(0, 0, 999999);
		cpAmount = new JCNumberField(0, 0, 99999);
		cpMemo = new JCScrollText();
		cpType = new JCComboBox();
		cpUser = new JCComboBox();
//		cpUnit = new JCComboBox();
		cpAmount.setNonNegative(true);
		cpMemo.getEditor().setLineWrap(true);

		firstRow.setLayout(new BoxLayout(firstRow, BoxLayout.X_AXIS));
		firstRow.setPreferredSize(new Dimension(-1, 25));
		secondRow.setLayout(new GridLayout(1, 2));
		// firstRow.add(ecDate = createTitledComponent(lbDate, cpDate, border,
		// 3));
		firstRow.add(ecOutId = createTitledComponent(lbOutId, cpOutId, border, 3));

		firstRow.add(ecType = createTitledComponent(lbType, cpType, border, 3));

		firstRow.add(ecAmount = createTitledComponent(lbAmount, cpAmount, border, 3));
		// firstRow.add(ecSummary = createTitledComponent(lbUnit, cpMemo,
		// border, 3));
//		firstRow.add(ecUnit = createTitledComponent(lbUnit, cpUnit, border, 3));

		// firstRow.add(ecRecordTime = createTitledComponent(lbRecordTime,
		// cpRecordTime, border, 3));
		firstRow.add(ecUser = createTitledComponent(lbUser, cpUser, null, 3));

		firstRow.setPreferredSize(new Dimension(-1, 24));
		secondRow.add(ecMemo = createTitledComponent(lbMemo, cpMemo, border, 3));
		// secondRow.add(ecRemark = createTitledComponent(lbMemo, cpRemark, new
		// EmptyBorder(0, 0, 0, 1), 3));
		ec.setLayout(new BorderLayout(0, 5));
		ec.setBorder(new EmptyBorder(3, 5, 2, 2));
		ec.add(firstRow, BorderLayout.NORTH);
		ec.add(secondRow, BorderLayout.CENTER);
		// ecDate.setPreferredSize(new Dimension(80, -1));
		ecOutId.setPreferredSize(new Dimension(50, -1));

		ecAmount.setPreferredSize(new Dimension(50, -1));
		// ecSummary.setPreferredSize(new Dimension(45, -1));
		ecType.setPreferredSize(new Dimension(28, -1));
//		ecUnit.setPreferredSize(new Dimension(28, -1));
		// ecRecordTime.setPreferredSize(new Dimension(105, -1));
		ecUser.setPreferredSize(new Dimension(40, -1));
		// cpRecordTime.setEditable(false);
		// cpRecordTime.setFocusable(false);
		// cpRecorder.setEditable(false);
		// cpRecorder.setFocusable(false);
		return ec;
	}


	@Override
	public String getType() {
		return "成品入库";
	}

	private JComponent createTitledComponent(JComponent titleComponent, JComponent component, Border border, int hgap) {
		EmptyComponent ec = new EmptyComponent();
		ec.setBorder(border);
		ec.setLayout(new BorderLayout(hgap, 0));
		ec.add(component, BorderLayout.CENTER);

		if (titleComponent != null) {
			ec.add(titleComponent, BorderLayout.WEST);
		}

		return ec;
	}

	//	private static final String[] COLUMNS_NAME = { "出仓流水", "成品数量", "当前库存", "应还数量", "状态",  "经手人", "最近修改时间"};
	protected JComponent createCenter() {
		final Class<?>[] columnsClass = { Integer.class, String.class, String.class, String.class, String.class,
				String.class, Timestamp.class };
		final String[] getMethodsName = { "getOutId", "getShouldProducts", "getRealProducts", "getNeedProducts", "getStatus", "getUser", "getCreated" };
		final String[] setMethodsName = { "setOutId",  "setShouldProducts", "setRealProducts", "setNeedProducts", "setStatus", "setUser", "setCreated" };		
		final int[] columnsPreferredWidth = { 16, 120, 120, 120, 20, 16, 80 };
		EmptyComponent ec = new EmptyComponent();
		JCScrollTable scTable = new JCScrollTable();
		table = scTable.getTable();
		model = new CommonTableModel<ProductOutCheck>(table, COLUMNS_NAME, columnsClass, getMethodsName, setMethodsName,
				data);
		TableRowSorter<CommonTableModel<ProductOutCheck>> sorter = new TableRowSorter<CommonTableModel<ProductOutCheck>>(
				model);

		scTable.setAlpha(0.0f);
		scTable.setColumnControlEnabled(false);
		// createLeftSplitButton();
		// createRightSplitButton();
		ec.setLayout(new BorderLayout());
		ec.add(scTable, BorderLayout.CENTER);
		table.setModel(model);
		table.setDragEnabled(false);
		table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		table.setRowSorter(sorter);
		table.setRendererOpaque(false);
		((JCTableHeader) table.getTableHeader()).setShowPopupMenu(false);

		for (int i = 0; i < columnsPreferredWidth.length; i++) {
			table.getColumnModel().getColumn(i).setPreferredWidth(columnsPreferredWidth[i]);
		}

		return center = ec;
	}

	@Override
	public void refresh() {
		loadData();
		model.delAllRow();
		model.setDataList(data);
		model.getTable().repaint();
		model.refreshRowOnView(0);
		
		loadTypes();
		loadUsers();
		keeper.refreshStatus();	}

}
